﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows;
using System.ComponentModel;
using DiagramCreator.Nodes;
using System.Windows.Media;
using System.Windows.Controls;

namespace DiagramCreator.Arrows
{
    public class ArrowLine : GenericConnectionLine
    {
        #region - Wymiary i DependencyProperties -        

        private double headHeight;
        public double HeadHeight
        {
            get { return headHeight; }
            set { headHeight = value; }
        }

        private double headWidth;
        public double HeadWidth
        {
            get { return headWidth; }
            set { headWidth = value; }
        }

        #endregion       

        #region - InternalDrawArrowGeometry -

        protected override void InternalDrawArrowGeometry(StreamGeometryContext context)
        {
            double theta = Math.Atan2(Y1 - Y2, X1 - X2);
            double sint = Math.Sin(theta);
            double cost = Math.Cos(theta);

            Point pt1 = new Point(X1, this.Y1);
            Point pt2 = new Point(X2, this.Y2);

            Point pt3 = new Point(
                X2 + (HeadWidth * cost - HeadHeight * sint),
                Y2 + (HeadWidth * sint + HeadHeight * cost));

            Point pt4 = new Point(
                X2 + (HeadWidth * cost + HeadHeight * sint),
                Y2 - (HeadHeight * cost - HeadWidth * sint));

            context.BeginFigure(pt1, true, false);
            context.LineTo(pt2, true, true);
            context.LineTo(pt3, true, true);
            context.LineTo(pt2, true, true);
            context.LineTo(pt4, true, true);                        
        }

        #endregion

        #region - Konstruktor -

        public ArrowLine(GenericNode p, GenericNode ch, Diagram.DiagramSheet sheet) : base(p, ch)
        {
            Sheet = sheet;
            this.MouseDown += new System.Windows.Input.MouseButtonEventHandler(ArrowLine_MouseDown);
        }     

        public override void Dispose()
        {
            base.Dispose();
            // usuwanie notatek związanych z linią
            if (Notes != null)
            {
                foreach (NoteNode n in Notes)
                    if (Sheet.Children.Contains(n))
                        Sheet.Children.Remove(n);
            }
        }

        void ArrowLine_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            CreateNoteNode(e.GetPosition(Sheet).X, e.GetPosition(Sheet).Y);
        }

        public List<NoteNode> Notes = new List<NoteNode>();

        public NoteNode CreateNoteNode(double x, double y)
        {
            NoteNode note = new NoteNode();
            Notes.Add(note);
            Sheet.Children.Add(note);
            note.Width = 50.0; note.Height = 35.0;
            note.SetValue(Canvas.TopProperty, y);
            note.SetValue(Canvas.LeftProperty, x);
            Sheet.addListenersToNode(note);
            note.NodeTextField.Focusable = true;            
            Sheet.selectNode(note);
            note.NodeTextField.Focus();
            note.NodeTextField.SelectAll();

            return note;
        }    

        public Diagram.DiagramSheet Sheet { get; set; }

        #endregion     

        public override void updatePosition()
        {
            base.updatePosition();
            // przesuwamy rowniez notatki do danej linii
            double offset = 0.0;
            foreach (NoteNode note in Notes)
            {
                note.SetValue(Canvas.TopProperty, Math.Min(Y1, Y2) + (Math.Abs(Y1 - Y2) - note.Height) / 2.0 + offset);
                note.SetValue(Canvas.LeftProperty, Math.Min(X1, X2) + Math.Abs(X1 - X2) / 2.0 - note.Width / 2.0);
                offset += note.Height + 5.0;
            }
        }
    }
}
